import java.util.Stack;

public class Solution {
    public static void main(String[] args) {
        Solution s = new Solution();
        System.out.println(s.calculate("1+2*3+4/5"));
    }

    public int calculate(String s) {
        /***
         * 基本计算器Ⅱ
         * 题目本质：
         *  给定有效的表达式，并保证所有参数和中间运算值都在int的表示范围之内，需要我们按照先乘除后加减的运算法则计算结果
         * 思路：
         *  <1> 暴力使用栈模拟，先计算乘除，后计算加减，此种方式比较直接，但是需要考虑的细节问题非常多
         *  <2> 使用栈 + 前置变量来解决（顺序解法，非常巧妙）
         * 对于老师代码的一些思考：
         *  1，循环处理字符串时，使用while循环可以让i的步进更加清晰
         *  2，对于空白字符串，手动跳过会节省空间（但是我认为需要额外考虑很多情况）
         *  3，多次函数调用，可以使用变量存储函数值，使代码美观
         * 核心解题思想：
         *  使用栈进行模拟，分情况讨论*/
        // 1 预处理
        Stack<Integer> stack = new Stack<>();
        char op = '+';
        // -清除s字符串中所有空格
        s = s.replaceAll(" ", "");

        // 2 循环处理字符串
        for(int i = 0; i < s.length(); i++) {
            // -数字和字符分开处理
            if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                // -1 数字
                // -- 提取整个数字（使用乘法比使用subString开销低得多）
                int cur = i;
                int curVal = 0;
                while(cur < s.length() && s.charAt(cur) >= '0' && s.charAt(cur) <= '9') {
                    curVal = curVal * 10 + (s.charAt(cur++) - '0');
                }
                // -- 根据前置操作符来决定当前操作
                if(op == '+') {
                    stack.push(curVal);
                } else if(op == '-') {
                    stack.push(-curVal);
                } else if(op == '*') {
                    stack.push(stack.pop() * curVal);
                } else if(op == '/') {
                    stack.push(stack.pop() / curVal);
                }
                // -- 更新位置
                i = cur - 1;
            } else {
                // -2 字符
                op = s.charAt(i);
            }
        }

        // 3 计算结果
        int answer = 0;
        while(!stack.isEmpty()) {
            answer += stack.pop();
        }

        // 4 返回值
        return answer;
    }
}
